/**
 * 根据传入的数据，解析为树结构数据
 * @param objectArray 对象数组
 * @param parentProp  父结构属性名
 * @returns           Array 树状结构对象数组
 */
export function treeOf(objectArray, parentProp="parentId") {
  if(!Array.isArray(objectArray)) return [];
  let results = new Set();
  //筛选出顶层数据，对原数组无影响
  let topSet = new Set(objectArray.filter(item=>!item[parentProp]));
  //筛选子自数据，对原数组无影响
  let childSet = new Set(objectArray.filter(item=>item[parentProp]));
  //循环转化树形结构
  topSet.forEach(item=>{
    results.add(getChildrenTree(item, childSet, parentProp));
  });
  return [...results];
}

/**
 * 获取对应数据的所有子数据，层级无限制
 * @param parentData          父对象，必须包含ID
 * @param array               待查找的数据集合，不会对其进行修改
 * @param containSelf         是否包含父元素自身
 * @param parentProp          父结构属性名
 * @returns                   Array 子数据数组
 */
export function childrenArrayOf(parentData, array, containSelf=false, parentProp="parentId") {
  let set = new Set(array);
  if(containSelf && array.some(item=>item.id === parentData.id)) {
    return [array.filter(item=>item.id === parentData.id)[0], ...getChildrenSet(parentData, set, parentProp)];
  }else {
    return [...getChildrenSet(parentData, set, parentProp)];
  }
}

/**
 * 获取对应数据的所有父数据，层级无限制
 * @param childData           子对象，必须包含id，若array中有该项，则parentProp可为空
 * @param array               待查找的数据集合，不会对其进行修改
 * @param containSelf         是否包含父元素自身
 * @param parentProp          父结构属性名
 * @returns                   Array 父数据数组，按层级从高向低顺序排列
 */
export function parentArrayOf(childData, array, containSelf=false, parentProp="parentId") {
  let set = new Set(array);
  if(containSelf && array.some(item=>item.id === childData.id)) {
    childData = array.filter(item=>item.id === childData.id)[0];
    return [...[...getParentSet(childData, set, parentProp)].reverse(), childData];
  } else {
    return [...[...getParentSet(childData, set, parentProp)].reverse()];
  }
}

/**
 * 获取对应数据的所有父数据，层级无限制
 * @param childData           子对象，必须包含parentProp
 * @param set                 待查找的数据集合，set
 * @param parentProp          父结构属性名, String
 * @returns                   Set 父数据数组，按层级从高向低顺序排列
 */
function getParentSet(childData, set, parentProp="parentId") {
  let parents = new Set();
  for (let parent of set) {
    if(parent.id === childData[parentProp]) {
      parents.add(parent);
      if([...set].some(item=>item.id === parent[parentProp])) {
        parents.add(...getParentSet(parent, set, parentProp));
      }
    }
  }
  return parents;
}

/**
 * 获取对应数据的所有子数据，层级无限制
 * @param parentData          父对象，必须包含ID
 * @param set                 待查找的数据集合，Set
 * @param parentProp          父结构属性名,String
 * @returns                   Set 子数据数组
 */
function getChildrenSet(parentData, set, parentProp="parentId") {
  let children = new Set();
  for (let child of set) {
    //查找子元素
    if(child[parentProp] === parentData.id) {
      children.add(child);
      // if([...set].some(item=>item[parentProp] === child.id)) {
      //   children.add(...getChildrenSet(child, set, parentProp));
      // }
      set.delete(child);
    }
  }
  return children;
}

/**
 * 获取对应数据的所有树状子数据，层级无限制
 * @param parentData               父级数据，Object
 * @param childSet                 待查找的子数据集合，Set
 * @param parentProp               父结构属性名，String
 * @returns {{children: Array}}    树状结构数据对象，Object
 */
function getChildrenTree(parentData, childSet, parentProp="parentId") {
  let children = new Set();
  for (let child of childSet) {
    if(child[parentProp] === parentData.id) {
      if([...childSet].some(item=>item[parentProp] === child.id)) {
        children.add(getChildrenTree(child, childSet, parentProp));
      }else {
        children.add(child);
      }
      childSet.delete(child);
    }
  }
  return {...parentData, children:[...children]};
}



// WEBPACK FOOTER //
// ./src/assets/js/utils/TreeUtils.js